﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.DB.Events;
using YArchitech.Controls;
using YArchitech.Revit;

namespace HYRElectric.PowerSystem
{
	public class LoopInfoManager
	{
		public LoopInfoManager(FamilyInstance fi, Document doc)
		{
			this.m_Panel = fi;
			this.m_doc = doc;
			Transaction transaction = new Transaction(doc, "SetNumber");
			transaction.Start();
			fi.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_NAMING).Set(0);
			transaction.Commit();
		}

		public string GetPanelNumber()
		{
			string text = this.m_Panel.get_Parameter(BuiltInParameter.RBS_ELEC_PANEL_NAME).AsString();
			if (text == null)
			{
				text = "";
			}
			return text;
		}

		public string GetPanelPrefix()
		{
			string text = this.m_Panel.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_PREFIX).AsString();
			if (text == null)
			{
				text = "";
			}
			return text;
		}

		public string GetPanelSeparator()
		{
			string text = this.m_Panel.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_PREFIX_SEPARATOR).AsString();
			if (text == null)
			{
				text = "";
			}
			return text;
		}

		public void GetLoopInfo(ref Dictionary<string, LoopInfoItem> dictionary)
		{
			if (this.m_Panel == null)
			{
				return;
			}
			ElectricalSystemSet electricalSystems = this.m_Panel.MEPModel.ElectricalSystems;
			if (electricalSystems == null)
			{
				return;
			}
			ElectricalSystemSetIterator electricalSystemSetIterator = electricalSystems.ForwardIterator();
			while (electricalSystemSetIterator.MoveNext())
			{
				object obj = electricalSystemSetIterator.Current;
				ElectricalSystem electricalSystem = obj as ElectricalSystem;
				List<ElementId> list = new List<ElementId>();
				List<ElementId> wireIds = new List<ElementId>();
				ElementSetIterator elementSetIterator = electricalSystem.Elements.ForwardIterator();
				while (elementSetIterator.MoveNext())
				{
					object obj2 = elementSetIterator.Current;
					Element element = obj2 as Element;
					list.Add(element.Id);
					this.GetConnectedWire(element, ref wireIds);
				}
				double num = electricalSystem.get_Parameter(BuiltInParameter.RBS_ELEC_APPARENT_LOAD).AsDouble();
				num = UnitConvert.CovertFromAPI((DisplayUnitType)84, num);
				LoopInfoItem value = new LoopInfoItem(num, electricalSystem.Id, list, wireIds);
				dictionary.Add(electricalSystem.Name, value);
			}
		}

		private void GetConnectedWire(Element elem, ref List<ElementId> lstWireId)
		{
			if (elem == null)
			{
				return;
			}
			ConnectorSetIterator connectorSetIterator = (elem as FamilyInstance).MEPModel.ConnectorManager.Connectors.ForwardIterator();
			while (connectorSetIterator.MoveNext())
			{
				object obj = connectorSetIterator.Current;
				Connector connector = obj as Connector;
				if (connector.IsConnected)
				{
					ConnectorSetIterator connectorSetIterator2 = connector.AllRefs.ForwardIterator();
					while (connectorSetIterator2.MoveNext())
					{
						object obj2 = connectorSetIterator2.Current;
						Connector connector2 = obj2 as Connector;
						ElementId id = connector2.Owner.Id;
						if (this.m_doc.GetElement(id) is Wire && !lstWireId.Contains(id))
						{
							lstWireId.Add(connector2.Owner.Id);
						}
					}
				}
			}
		}

		private void OnFailuresProcessing(object sender, FailuresProcessingEventArgs e)
		{
			e.GetFailuresAccessor().DeleteAllWarnings();
		}

		public void AddNewLoop(IList<Reference> lstEquips)
		{
			if (this.m_Panel == null || lstEquips == null)
			{
				return;
			}
			Transaction transaction = new Transaction(this.m_doc, "NewLoop");
			this.m_doc.Application.FailuresProcessing += this.OnFailuresProcessing;
			transaction.Start();
			try
			{
				IEnumerable<Element> enumerable = new FilteredElementCollector(this.m_doc).OfClass(typeof(ElectricalSystem)).ToElements();
				bool flag = true;
				foreach (Element element in enumerable)
				{
					ElectricalSystem electricalSystem = element as ElectricalSystem;
					ElementSet elements = electricalSystem.Elements;
					ElementSet elementSet = new ElementSet();
					foreach (Reference reference in lstEquips)
					{
						Element element2 = this.m_doc.GetElement(reference);
						if (elements.Contains(element2))
						{
							if (flag)
							{
								if (YJKMessageBox.Show("某些构件已存在其他回路当中，是否删将其从已有回路中删除，并添加到新回路中？", MessageBoxButtons.YesNo) == DialogResult.No)
								{
									return;
								}
								flag = false;
							}
							elementSet.Insert(element2);
						}
					}
					if (elementSet.Size > 0)
					{
						electricalSystem.RemoveFromCircuit(elementSet);
					}
				}
				ICollection<ElementId> collection = new List<ElementId>();
				foreach (Reference reference2 in lstEquips)
				{
					collection.Add(reference2.ElementId);
				}
				if (collection.Count > 0)
				{
                    this.m_doc.Create.NewElectricalSystem(collection, (Autodesk.Revit.DB.Electrical.ElectricalSystemType)6).SelectPanel(this.m_Panel);
				}
				transaction.Commit();
			}
			catch
			{
				transaction.RollBack();
			}
		}

		public void DeleteLoop(ElementId loopId)
		{
			if (loopId == null)
			{
				return;
			}
			Transaction transaction = new Transaction(this.m_doc, "DeleteLoop");
			transaction.Start();
			try
			{
				this.m_doc.GetElement(loopId);
				this.m_doc.Delete(loopId);
				transaction.Commit();
			}
			catch
			{
				transaction.RollBack();
			}
		}

		public void AddEquipsToLoop(ElementId loopId, IList<Reference> lstEquips)
		{
			if (this.m_Panel == null || loopId == null || lstEquips.Count <= 0)
			{
				return;
			}
			ElectricalSystem electricalSystem = this.m_doc.GetElement(loopId) as ElectricalSystem;
			if (electricalSystem == null)
			{
				return;
			}
			Transaction transaction = new Transaction(this.m_doc, "AddDelete");
			transaction.Start();
			try
			{
				ElementSet elementSet = new ElementSet();
				foreach (Reference reference in lstEquips)
				{
					Element element = this.m_doc.GetElement(reference);
					ElementId elementId = reference.ElementId;
					if (!electricalSystem.Elements.Contains(element))
					{
						elementSet.Insert(element);
					}
				}
				if (elementSet.Size > 0)
				{
					electricalSystem.AddToCircuit(elementSet);
				}
				ElectricalSystemSetIterator electricalSystemSetIterator = this.m_Panel.MEPModel.ElectricalSystems.ForwardIterator();
				while (electricalSystemSetIterator.MoveNext())
				{
					object obj = electricalSystemSetIterator.Current;
					ElectricalSystem electricalSystem2 = obj as ElectricalSystem;
					if (!(electricalSystem2.Id == loopId))
					{
						ElementSet elements = electricalSystem2.Elements;
						ElementSet elementSet2 = new ElementSet();
						foreach (Reference reference2 in lstEquips)
						{
							Element element2 = this.m_doc.GetElement(reference2);
							if (elements.Contains(element2))
							{
								elementSet2.Insert(element2);
							}
						}
						if (elementSet2.Size > 0)
						{
							electricalSystem2.RemoveFromCircuit(elementSet2);
						}
					}
				}
				transaction.Commit();
			}
			catch
			{
				transaction.RollBack();
			}
		}

		public void ModifyLoopNumber(string strPrefix)
		{
			if (this.m_Panel == null)
			{
				return;
			}
			Transaction transaction = new Transaction(this.m_doc, "Modify Loop Number");
			transaction.Start();
			this.m_Panel.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_PREFIX).Set(strPrefix);
			transaction.Commit();
		}

		public void ModifySwitchBoxNum(string strSwitchBoxNum)
		{
			if (this.m_Panel == null)
			{
				return;
			}
			Transaction transaction = new Transaction(this.m_doc, "Modify SwitchBox Number");
			transaction.Start();
			this.m_Panel.get_Parameter(BuiltInParameter.RBS_ELEC_PANEL_NAME).Set(strSwitchBoxNum);
			transaction.Commit();
		}

		public void ModifySeparator(string strSeparator)
		{
			if (this.m_Panel == null)
			{
				return;
			}
			Transaction transaction = new Transaction(this.m_doc, "Modify Separator");
			transaction.Start();
			this.m_Panel.get_Parameter(BuiltInParameter.RBS_ELEC_CIRCUIT_PREFIX_SEPARATOR).Set(strSeparator);
			transaction.Commit();
		}

		private FamilyInstance m_Panel;

		private Document m_doc;
	}
}
